﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using BGShell.Configuration;

namespace BGShell
{
    internal sealed class BGShellAddInManager
    {
        private readonly List<BGShellAddIn> _addins = new List<BGShellAddIn>();
        private readonly List<Type> _tabTypes = new List<Type>();

        private ReadOnlyCollection<BGShellAddIn> _addinCollection;
        private ReadOnlyCollection<Type> _tabTypeCollection;

        private Type _defaultTabType;

        internal BGShellAddInManager(BGShellSection configSection)
        {
            LoadAddInsFrom(Assembly.GetExecutingAssembly(), true);

            if (configSection != null)
            {
                foreach (BGShellAddInElement addinElement in configSection.AddIns)
                {
                    var addinAssembly = addinElement.LoadAssembly();

                    if (addinAssembly != null)
                    {
                        LoadAddInsFrom(addinAssembly, false);
                    }
                }
            }
        }

        public ReadOnlyCollection<BGShellAddIn> AddIns
        {
            get
            {
                if (_addinCollection == null)
                {
                    _addinCollection = _addins.AsReadOnly();
                }

                return _addinCollection;
            }
        }

        public ReadOnlyCollection<Type> TabTypes
        {
            get
            {
                if (_tabTypeCollection == null)
                {
                    _tabTypeCollection = _tabTypes.AsReadOnly();
                }

                return _tabTypeCollection;
            }
        }

        public Type DefaultTabType
        {
            get
            {
                if ((_defaultTabType == null) && (_tabTypes != null) && (_tabTypes.Count > 0))
                {
                    return _tabTypes[0];
                }

                return _defaultTabType;
            }
            set { _defaultTabType = value; }
        }

        internal void InitializeAddins(BGShellApplication app)
        {
            foreach (var addin in _addins)
            {
                addin.OnApplicationStartup(app);
            }
        }

        private void LoadAddInsFrom(Assembly assembly, Boolean includeInternal)
        {
            var addins = BGShellAddIn.LoadFrom(assembly, includeInternal);

            foreach (var addin in addins)
            {
                _tabTypes.AddRange(addin.GetTabTypes());
            }

            _addins.AddRange(addins);
        }
    }
}
